package com.fiberhome.opticalbox.ui;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.litepal.crud.DataSupport;

import android.app.Dialog;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.fiberhome.opticalbox.R;
import com.fiberhome.opticalbox.BaseActivity;
import com.fiberhome.opticalbox.db.model.DBAttachInfo;
import com.fiberhome.opticalbox.net.NetConstant;
import com.fiberhome.opticalbox.net.NetManager.TcpErrorListener;
import com.fiberhome.opticalbox.net.NetManager.TcpListener;
import com.fiberhome.opticalbox.net.bean.Parameter;
import com.fiberhome.opticalbox.net.bean.Parameter.MACInfo;
import com.fiberhome.opticalbox.net.utils.JsonUtil;
import com.fiberhome.opticalbox.utils.LogUtil;
import com.fiberhome.opticalbox.utils.NetworkUtil;
import com.fiberhome.opticalbox.view.SurfManageInfoLayout;
import com.fiberhome.opticalbox.view.TitleView;
import com.fiberhome.opticalbox.view.third.stickylist.ExpandableStickyListHeadersListView;
import com.fiberhome.opticalbox.view.third.stickylist.StickyListHeadersAdapter;
import com.fiberhome.opticalbox.view.third.stickylist.StickyListHeadersListView;

/**
 * 防蹭网
 * 
 * @author wangpeng
 * 
 */
public class SurfManageActivity extends BaseActivity {

	private String[] surfManageType;
	private LinkedList<SurfManageInfo> deviceList = new LinkedList<SurfManageInfo>();
	private StickyListHeadersAdapter adapter = new DeviceManageAdapter();
	private ExpandableStickyListHeadersListView expandableStickyList;

	private Dialog dlgLoading;
	private ImageView imgSurfManage;

	@Override protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.ob_activity_surf_manage);

		surfManageType = getResources().getStringArray(R.array.ob_surf_manage_type);

		titleView = (TitleView) findViewById(R.id.ob_titleView);
		titleView.setTitle(R.string.ob_surf_private);
		titleView.setBackground(R.drawable.ob_bg_title);
		titleView.addLeftDrawableMenu(this, R.drawable.ob_ico_back, 15, 25, onBackClickListener);

		imgSurfManage = (ImageView) findViewById(R.id.img_surf_manage);
		((AnimationDrawable) imgSurfManage.getDrawable()).start();

		expandableStickyList = (ExpandableStickyListHeadersListView) findViewById(R.id.ob_listView);
		expandableStickyList.setAdapter(adapter);
		expandableStickyList.setOnHeaderClickListener(new StickyListHeadersListView.OnHeaderClickListener() {
			@Override public void onHeaderClick(StickyListHeadersListView l, View header, int itemPosition, long headerId,
					boolean currentlySticky) {
				if (expandableStickyList.isHeaderCollapsed(headerId)) {
					expandableStickyList.expand(headerId);
				} else {
					expandableStickyList.collapse(headerId);
				}
			}
		});

		expandableStickyList.setOnTouchListener(new OnTouchListener() {
			@Override public boolean onTouch(View v, MotionEvent event) {
				return false;
			}
		});

		registerChildTcpListener(tcpListener);
		registerChildTcpErrorListener(tcpErrorListener);

		requestGetWlanAttachInfo();
	}

	/** surf manage adapter model */
	public static class SurfManageInfo {
		public String MAC;
		public String InternetAccessRight;
		public String DaysOfWeek;
		public String StartTime;
		public String EndTime;
		public String HostName;

		public int type;
		public boolean isMenuOpen = false;

		public static final int TYPE_ENABLE = 0;
		public static final int TYPE_DISABLE = 1;

		public SurfManageInfo(int type) {
			this.type = type;
		}

		public String getNickName() {
			List<DBAttachInfo> mDBAttachInfoList = DataSupport.where("mac = ?", MAC).find(DBAttachInfo.class);
			if (mDBAttachInfoList != null && mDBAttachInfoList.size() > 0) {
				DBAttachInfo mDBAttachInfo = mDBAttachInfoList.get(0);
				return mDBAttachInfo.getNickname();
			}
			return "";
		}

		public static List<SurfManageInfo> convert(String[] arrDevice) {
			if (arrDevice == null) {
				return null;
			}
			List<SurfManageInfo> deviceList = new ArrayList<SurfManageActivity.SurfManageInfo>();
			for (int i = 0; i < arrDevice.length; i++) {
				String[] arrParam = arrDevice[i].split(" ");
				if (arrParam != null) {
					SurfManageInfo device = new SurfManageInfo(TYPE_ENABLE);
					for (String param : arrParam) {
						if (param.startsWith("MAC:")) {
							device.MAC = param.substring("MAC:".length());
						}
						if (param.startsWith("NAME:")) {
							device.HostName = param.substring("NAME:".length());
						}
					}
					deviceList.add(device);
				}
			}
			return deviceList;
		}

		public static List<SurfManageInfo> merge(List<SurfManageInfo> master, List<MACInfo> MACInfoList) {
			if (master != null && master.size() > 0) {
				if (MACInfoList != null && MACInfoList.size() > 0) {
					for (SurfManageInfo device : master) {
						for (MACInfo macInfo : MACInfoList) {
							if (device != null && device.MAC != null && device.MAC.equals(macInfo.MAC)) {
								device.type = "OFF".equals(macInfo.InternetAccessRight) ? TYPE_ENABLE : TYPE_DISABLE;
								break;
							}
						}
					}
				}
			}
			return master;
		}

		public static LinkedList<SurfManageInfo> sort(List<SurfManageInfo> deviceList) {
			LinkedList<SurfManageInfo> sortResult = new LinkedList<SurfManageActivity.SurfManageInfo>();
			for (SurfManageInfo device : deviceList) {
				if (SurfManageInfo.TYPE_ENABLE == device.type) {
					sortResult.add(device);
				}
			}
			for (SurfManageInfo device : deviceList) {
				if (SurfManageInfo.TYPE_DISABLE == device.type) {
					sortResult.add(device);
				}
			}
			return sortResult;
		}
	}

	public void setDeviceDisable(SurfManageInfo surfManageInfo) {
		if (surfManageInfo == null) {
			LogUtil.e("setDeviceDisable() surfManageInfo is null");
			return;
		}
		showLoadingDialog(R.string.ob_wait_ctrl_manage);
		requestSetAttachDevciceInfo(surfManageInfo, "ON");
	}

	public void setDeviceEnable(SurfManageInfo surfManageInfo) {
		if (surfManageInfo == null) {
			LogUtil.e("setDeviceEnable() surfManageInfo is null");
			return;
		}
		showLoadingDialog(R.string.ob_wait_ctrl_manage);
		requestSetAttachDevciceInfo(surfManageInfo, "OFF");
	}

	public class DeviceManageAdapter extends BaseAdapter implements StickyListHeadersAdapter {
		@Override public int getCount() {
			return deviceList.size();
		}

		@Override public Object getItem(int position) {
			return deviceList.get(position);
		}

		@Override public long getItemId(int position) {
			return position;
		}

		@Override public View getView(int position, View convertView, ViewGroup parent) {
			int type = getItemViewType(position);
			final SurfManageInfo smi = (SurfManageInfo) getItem(position);
			View view = null;
			if (convertView == null) {
				switch (type) {
				case SurfManageInfo.TYPE_ENABLE:
					view = new SurfManageInfoLayout(SurfManageActivity.this);
					break;
				case SurfManageInfo.TYPE_DISABLE:
					view = inflater.inflate(R.layout.ob_list_content_device_disable, null);
					break;
				}
			} else {
				view = convertView;
			}

			switch (type) {
			case SurfManageInfo.TYPE_ENABLE:
				// fix class cast exception ?
				if (!(view instanceof SurfManageInfoLayout)) {
					view = new SurfManageInfoLayout(SurfManageActivity.this);
				}
				((SurfManageInfoLayout) view).setSurfManageInfo(smi);
				break;
			case SurfManageInfo.TYPE_DISABLE:
				// fix class cast exception ?
				if (!(view instanceof LinearLayout)) {
					view = inflater.inflate(R.layout.ob_list_content_device_disable, null);
				}
				TextView txName = (TextView) view.findViewById(R.id.tx_name);
				String name = getString(R.string.ob_device_unknown);
				if (!TextUtils.isEmpty(smi.getNickName())) {
					name = smi.getNickName();
				} else {
					if (!TextUtils.isEmpty(smi.HostName)) {
						name = smi.HostName;
					}
				}
				txName.setText(name);
				TextView txMac = (TextView) view.findViewById(R.id.tx_mac);
				txMac.setText(smi.MAC);
				final Button button = (Button) view.findViewById(R.id.ob_button);
				button.setVisibility(View.VISIBLE);
				button.setOnClickListener(new OnClickListener() {
					@Override public void onClick(View view) {
						button.setVisibility(View.GONE);
						smi.isMenuOpen = false;
						setDeviceEnable(smi);
					}
				});
				break;
			}
			return view;
		}

		@Override public View getHeaderView(int position, View convertView, ViewGroup parent) {
			HeaderViewHolder viewHolder;
			if (convertView == null) {
				viewHolder = new HeaderViewHolder();
				convertView = inflater.inflate(R.layout.ob_list_head_surf_manage, parent, false);
				viewHolder.text = (TextView) convertView.findViewById(R.id.text);
				convertView.setTag(viewHolder);
			} else {
				viewHolder = (HeaderViewHolder) convertView.getTag();
			}
			String headerText = surfManageType[deviceList.get(position).type];

			viewHolder.text.setText(headerText);
			return convertView;
		}

		@Override public long getHeaderId(int position) {
			SurfManageInfo i = deviceList.get(position);
			return i.type;
		}

		@Override public int getItemViewType(int position) {
			SurfManageInfo i = deviceList.get(position);
			return i.type;
		}

		@Override public int getViewTypeCount() {
			return 2;
		}

		class HeaderViewHolder {
			TextView text;
		}
	}

	private void requestGetWlanAttachInfo() {
		netManager.sendTcp(JsonUtil.get_GET_WLAN_ATTACH_INFO());
	}

	private void requestGetAttachDevciceInfo() {
		netManager.sendTcp(JsonUtil.get_GET_ATTACH_DEVICE_RIGHT("1"));
	}

	private void requestSetAttachDevciceInfo(SurfManageInfo smi, String internetEnable) {
		String MAC = smi.MAC;
		String InternetAccessRight = internetEnable;
		String StartTime = smi.StartTime != null ? smi.StartTime : "";
		String EndTime = smi.EndTime != null ? smi.EndTime : "";

		String dowDefault = "OFF".equals(InternetAccessRight) ? "1111111" : "0000000";
		String DaysOfWeek = smi.DaysOfWeek != null ? smi.DaysOfWeek : dowDefault;
		String ControlWifiMode = "1";
		netManager.sendTcp(JsonUtil.get_SET_ATTACH_DEVICE_RIGHT(MAC, InternetAccessRight, StartTime, EndTime, DaysOfWeek, ControlWifiMode));
	}

	private TcpListener tcpListener = new TcpListener() {
		@Override public void onReceive(String cmdType, Parameter param) {
			if (NetConstant.GET_WLAN_ATTACH_INFO.equals(cmdType)) {
				if (!TextUtils.isEmpty(param.Info)) {
					String[] arrDevice = param.Info.split("/");
					deviceList.clear();
					deviceList.addAll(SurfManageInfo.convert(arrDevice));

					requestGetAttachDevciceInfo();
				}
			} else if (NetConstant.GET_ATTACH_DEVICE_RIGHT.equals(cmdType)) {
				imgSurfManage.setVisibility(View.GONE);
				if (param.MACList != null) {
					SurfManageInfo.merge(deviceList, param.MACList);
				}
				LinkedList<SurfManageInfo> sortResult = SurfManageInfo.sort(deviceList);
				deviceList.clear();
				deviceList.addAll(sortResult);
				adapter.notifyDataSetChanged();
			} else if (NetConstant.SET_ATTACH_DEVICE_RIGHT.equals(cmdType)) {
				if (dlgLoading != null) {
					dlgLoading.dismiss();
				}
				requestGetWlanAttachInfo();
			}
		}
	};

	private TcpErrorListener tcpErrorListener = new TcpErrorListener() {
		@Override public void onError(String cmdType) {
			if (NetConstant.GET_WLAN_ATTACH_INFO.equals(cmdType)) {
				imgSurfManage.setVisibility(View.GONE);
			} else if (NetConstant.GET_ATTACH_DEVICE_RIGHT.equals(cmdType)) {
				imgSurfManage.setVisibility(View.GONE);
			} else if (NetConstant.SET_ATTACH_DEVICE_RIGHT.equals(cmdType)) {
				if (dlgLoading != null) {
					dlgLoading.dismiss();
				}
			}
			showToast(NetworkUtil.isDisconnected(SurfManageActivity.this) ? R.string.ob_error_net : R.string.ob_error_request);
		}
	};

	private void showLoadingDialog(int title) {
		dlgLoading = dialogUtil.createLoading(title, false, true).show();
	}
}